﻿using System;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using SecretLabs.NETMF.Hardware;
using SecretLabs.NETMF.Hardware.Netduino;
using System.IO.Ports;
using System.Collections;

namespace NetduinoPlusControllerMain
{
    public class Ping
    {
        private TristatePort _port;

        // Pass in the pin to which the rangefinder is attached.
        public Ping(Cpu.Pin pin)
        {
            _port = new TristatePort(pin, false, false, ResistorModes.Disabled);
        }

        // Returns distance in mm
        public int mm_Distance()
        {

            // First we need to pulse the port ... high, low.  It seems to work fine, without adding any delay.
            _port.Active = true;                // Put port in write mode
            _port.Write(true);                  // Pulse pin
            _port.Write(false);

            _port.Active = false;                        // Put port in read mode;    
            bool v1 = false;
            while (v1 == false) { v1 = _port.Read(); }   // Wait for line to go high.
            long tick1 = System.DateTime.Now.Ticks;      // Save start ticks.

            bool v2 = true;
            while (v2 == true) { v2 = _port.Read(); }    // Wait for line to go low.
            long tick2 = System.DateTime.Now.Ticks;      // Save end ticks. 

            int ticks = (int)(tick2 - tick1);
            // Now, just have to convert ticks to mm
            //   Per wikipedia: speed of sound, dry air, 20 deg C, 343 m /s
            //   Per msdn: one .NET "Tick" = 0.1 micro seconds.
            // Which works out to ... 
            // ... 1 mm of travel each 29.15 ticks
            // ... divide by 2 for round-trip ... 58.3 ticks per mm

            return ticks * 10 / 583;
        }
    }

    public class Program
    {
        static SerialPort com;
        static Ping ping;
        public static void Main()
        {
            Queue distanceValues = new Queue();
            com = new SerialPort(SerialPorts.COM1, 9600, Parity.None, 8, StopBits.One);
            com.Open();
            com.DataReceived += new SerialDataReceivedEventHandler(com_DataReceived);
            //Ping ping = new Ping(Pins.GPIO_PIN_D7);
            ping = new Ping(Pins.GPIO_PIN_D7);
            while (true)
            {
                int cm = ping.mm_Distance() / 10;
                if (cm < 30)
                {
                    CrossPlatform.CrossPlatformMessagesForSumpPump sumpPumpMessages = new CrossPlatform.CrossPlatformMessagesForSumpPump();
                    string destanceEvent =
                        sumpPumpMessages.createSumpPumpEventMessage(DateTime.Now, "Alarm", "Distance was too small at " + cm + " cm");
                    Debug.Print(destanceEvent);
                    com.Write(System.Text.Encoding.UTF8.GetBytes(destanceEvent), 0, destanceEvent.Length);
                }
                if (cm > 100)
                {
                    CrossPlatform.CrossPlatformMessagesForSumpPump sumpPumpMessages = new CrossPlatform.CrossPlatformMessagesForSumpPump();
                    string destanceEvent =
                        sumpPumpMessages.createSumpPumpEventMessage(DateTime.Now, "Alarm", "Distance was too large at " + cm + " cm");
                    Debug.Print(destanceEvent);
                    com.Write(System.Text.Encoding.UTF8.GetBytes(destanceEvent), 0, destanceEvent.Length);
                }
                //distanceValues.Enqueue(cm);
                Debug.Print(cm.ToString() + "cm");
                //Thread.Sleep(5000);
                Thread.Sleep(2000);
            }
        }

        static void com_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            byte[] bytes = new byte[1];
            com.Read(bytes, 0, bytes.Length);

            if (bytes[0] == 'd')
            {
                int cm = ping.mm_Distance() / 10;
                //string currentDistance = "Distance = " + cm.ToString() + "cm";
                CrossPlatform.CrossPlatformMessagesForSumpPump sumpPumpMessages = new CrossPlatform.CrossPlatformMessagesForSumpPump();
                string currentDistance = sumpPumpMessages.createSumpPumpStatusMessage(cm, -27);
                Debug.Print(currentDistance);
                com.Write(System.Text.Encoding.UTF8.GetBytes(currentDistance), 0, currentDistance.Length);
            }
            else
            {
                com.Write(bytes, 0, bytes.Length);
            }
        }
    }
}




